const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const Dotenv = require('dotenv-webpack');

let geppettoConfig;
try {
  geppettoConfig = require('./GeppettoConfiguration.json');
  console.log('\n✓ Loaded Geppetto config from file');
} catch (e) {
  console.error('\n✗ Failed to load Geppetto Configuration');
  process.exit(1);
}

const geppettoClientPath = 'node_modules/@metacell/geppetto-meta-client';
const geppettoCorePath = 'node_modules/@metacell/geppetto-meta-core';
const geppettoUIPath = 'node_modules/@metacell/geppetto-meta-ui';

const isProduction = process.env.NODE_ENV === 'production';

// 在开发模式下使用简单路径，生产模式使用 Geppetto 路径
const publicPath = isProduction 
  ? path.join('/', geppettoConfig.contextPath, 'geppetto/build/')
  : '/';
console.log(`\n✓ Public path: ${publicPath}`);
const envFile = isProduction ? '.env.production' : '.env.development';
console.log(`\n✓ Building for ${isProduction ? 'production' : 'development'} environment`);
console.log(`\n✓ Using config from: ${envFile}`);

// 从环境变量读取配置（带默认值）
const getEnvVar = (key, defaultValue) => {
  const value = process.env[key];
  if (value === 'true') return true;
  if (value === 'false') return false;
  return value !== undefined ? value : defaultValue;
};

const isWin = process.platform === 'win32';
console.log(`\n✓ Building on ${isWin ? 'Windows' : 'Unix'} platform`);

let cssThemesPath = path.resolve(__dirname, geppettoConfig.themes);
if (isWin) {
  cssThemesPath = cssThemesPath.replace(/\\/g, '/');
}

const availableExtensions = [
  {
    from: path.resolve(__dirname, geppettoClientPath, 'style/fonts/*'),
    to: 'static/fonts/[name][ext]',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, geppettoClientPath, 'style/css/font-awesome.min.css'),
    to: 'static/css',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, geppettoClientPath, 'style/css/gpt-icons.css'),
    to: 'static/css',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, geppettoClientPath, 'static/*'),
    to: 'static/[name][ext]',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, geppettoCorePath, 'static/*'),
    to: 'static/[name][ext]',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, geppettoUIPath, 'static/*'),
    to: 'static/[name][ext]',
    noErrorOnMissing: true,
  },
  {
    from: path.resolve(__dirname, 'static'),
    to: 'static',
    noErrorOnMissing: true,
  },
];

module.exports = (env = {}) => {
  // 从 .env 文件覆盖 Geppetto 配置
  if (process.env.GEPPETTO_USE_SSL !== undefined) {
    geppettoConfig.useSsl = getEnvVar('GEPPETTO_USE_SSL', false);
  }
  if (process.env.GEPPETTO_EMBEDDED !== undefined) {
    geppettoConfig.embedded = getEnvVar('GEPPETTO_EMBEDDED', true);
  }
  
  // Override config from webpack env parameter
  if (env.contextPath) {
    geppettoConfig.contextPath = env.contextPath;
  }
  if (env.useSsl) {
    geppettoConfig.useSsl = JSON.parse(env.useSsl);
  }
  if (env.noTest) {
    geppettoConfig.noTest = JSON.parse(env.noTest);
  }
  if (env.embedded) {
    geppettoConfig.embedded = JSON.parse(env.embedded);
  }
  if (env.embedderURL) {
    geppettoConfig.embedderURL = env.embedderURL;
  }

  console.log('\n✓ Geppetto configuration:');
  console.log(JSON.stringify(geppettoConfig, null, 2), '\n');

  const entries = {
    main: path.resolve(__dirname, 'src/index.tsx'),
  };

  console.log('\n✓ Webpack entries:');
  console.log(entries);

  return {
    entry: entries,
    mode: isProduction ? 'production' : 'development',
    devtool: isProduction 
      ? (getEnvVar('BUILD_SOURCE_MAP', 'true') === 'false' ? false : 'source-map')
      : (getEnvVar('BUILD_SOURCE_MAP', 'true') === 'false' ? false : 'eval-source-map'),

    optimization: {
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
          },
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            priority: -10,
            reuseExistingChunk: true,
          },
        },
      },
    },

    output: {
      path: path.resolve(__dirname, 'build'),
      filename: isProduction ? '[name].[contenthash].bundle.js' : '[name].bundle.js',
      chunkFilename: isProduction ? '[name].[contenthash].chunk.js' : '[name].chunk.js',
      publicPath,
      clean: true,
    },

    plugins: [
      new Dotenv({
        path: envFile,
        safe: false, // 如果 .env 文件不存在，不报错
        systemvars: true, // 允许系统环境变量覆盖 .env 文件
      }),
      new CopyWebpackPlugin({
        patterns: availableExtensions,
      }),
      // 生成 index.html 用于独立运行（不使用 contextPath）
      new HtmlWebpackPlugin({
        filename: 'index.html',
        template: path.resolve(__dirname, 'index.ejs'),
        inject: 'body',
        publicPath: './',
        minify: isProduction ? {
          removeComments: true,
          collapseWhitespace: true,
          removeRedundantAttributes: true,
        } : false,
      }),
      // 生成 geppetto.vm 用于嵌入式部署
      new HtmlWebpackPlugin({
        filename: 'geppetto.vm',
        template: path.resolve(__dirname, 'geppetto.ejs'),
        GEPPETTO_CONFIGURATION: geppettoConfig,
        chunks: [],
        minify: isProduction ? {
          removeComments: true,
          collapseWhitespace: true,
          removeRedundantAttributes: true,
        } : false,
      }),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
      }),
      new MiniCssExtractPlugin({
        filename: isProduction ? '[name].[contenthash].css' : '[name].css',
        chunkFilename: isProduction ? '[id].[contenthash].css' : '[id].css',
      }),
    ],

    resolve: {
      alias: {
        root: path.resolve(__dirname),
        'geppetto-client': path.resolve(__dirname, geppettoClientPath),
        'geppetto-core': path.resolve(__dirname, geppettoCorePath),
        'geppetto-ui': path.resolve(__dirname, geppettoUIPath),
        geppetto: path.resolve(__dirname, geppettoClientPath, 'pages/geppetto/GEPPETTO.js'),
        'geppetto-client-initialization': path.resolve(__dirname, geppettoClientPath, 'pages/geppetto/main.js'),
        handlebars: 'handlebars/dist/handlebars.js',
        netpyne: path.resolve(__dirname),
        '@': path.resolve(__dirname, 'src'),
        '@components': path.resolve(__dirname, 'src/components'),
        '@redux': path.resolve(__dirname, 'src/redux'),
        '@utils': path.resolve(__dirname, 'src/utils'),
        '@constants': path.resolve(__dirname, 'src/constants'),
      },
      extensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
      fallback: {
        fs: false,
        child_process: false,
        module: false,
      },
    },

    module: {
      rules: [
        {
          test: /\.(ts|tsx|js|jsx)$/,
          // 只处理需要转译的代码：src 目录和 geppetto 包
          include: [
            path.resolve(__dirname, 'src'),
            path.resolve(__dirname, geppettoClientPath),
            path.resolve(__dirname, geppettoCorePath),
            path.resolve(__dirname, geppettoUIPath),
          ],
          exclude: [
            /ami.min.js/,
            // 明确排除大型已编译库，即使它们在 geppetto 包的依赖中
            /node_modules\/@mui\/icons-material/,
            /node_modules\/@fortawesome\/free-solid-svg-icons/,
            /node_modules\/three/,
            /node_modules\/@mui\/material/,
            /node_modules\/@mui\/lab/,
            /node_modules\/@fortawesome\/fontawesome-svg-core/,
            /node_modules\/@fortawesome\/react-fontawesome/,
          ],
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                ['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }],
                '@babel/preset-react',
                '@babel/preset-typescript',
              ],
              plugins: [
                '@babel/plugin-syntax-dynamic-import',
                '@babel/plugin-proposal-class-properties',
                '@babel/plugin-transform-runtime',
              ],
              sourceType: 'unambiguous',
              compact: false, // 禁用紧凑模式，避免大文件的警告
            },
          },
        },
        {
          test: /Dockerfile/,
          loader: 'ignore-loader',
        },
        {
          test: /\.(py|jpeg|svg|gif|jpg|md|hbs|dcm|gz|xmi|dzi|sh|obj|yml|nii)$/,
          loader: 'ignore-loader',
        },
        {
          test: /\.(png|eot|ttf|woff|woff2|svg)(\?[a-z0-9=.]+)?$/,
          type: 'asset',
          parser: {
            dataUrlCondition: {
              maxSize: 100000,
            },
          },
        },
        {
          test: /\.css$/,
          use: isProduction
            ? [
                MiniCssExtractPlugin.loader,
                'css-loader',
              ]
            : [
                'style-loader',
                'css-loader',
              ],
        },
        {
          test: /\.s[a|c]ss$/,
          use: [
            'style-loader',
            'css-loader',
            'sass-loader',
          ],
        },
        {
          test: /\.less$/,
          use: [
            { loader: 'style-loader' },
            { loader: 'css-loader' },
            {
              loader: 'less-loader',
              options: {
                lessOptions: {
                  modifyVars: { url: path.resolve(__dirname, geppettoConfig.themes) },
                },
              },
            },
          ],
        },
        {
          test: /\.html$/,
          loader: 'raw-loader',
        },
      ],
    },

    devServer: {
      static: {
        directory: path.join(__dirname, 'build'),
        publicPath: '/',
      },
      port: parseInt(getEnvVar('DEV_SERVER_PORT', '8081'), 10),
      host: getEnvVar('DEV_SERVER_HOST', 'localhost'),
      hot: getEnvVar('DEV_SERVER_HOT', 'true') !== 'false',
      compress: getEnvVar('DEV_SERVER_COMPRESS', 'false') === 'true',
      historyApiFallback: true,
      // 禁用代理，前端独立运行
      // proxy: [
      //   {
      //     context: ['/org.geppetto.frontend'],
      //     target: (getEnvVar('API_BASE_URL', 'http://localhost:8888')).replace('http://', 'ws://').replace('https://', 'wss://'),
      //     ws: true,
      //     onError: (err, req, res) => {
      //       console.warn('WebSocket proxy error (backend may not be running):', req.url);
      //     },
      //   },
      //   {
      //     context: ['/notebooks', '/api', '/api/kernels', '/static', '/custom', '/nbextensions'],
      //     target: getEnvVar('API_BASE_URL', 'http://localhost:8888'),
      //     changeOrigin: true,
      //     onError: (err, req, res) => {
      //       console.warn('API proxy error (backend may not be running):', req.url);
      //     },
      //   },
      // ],
      client: {
        overlay: {
          errors: true,
          warnings: false,
        },
      },
    },

    performance: {
      hints: isProduction ? 'warning' : false,
      maxEntrypointSize: 512000,
      maxAssetSize: 512000,
    },
  };
};

